#include <math.h>
#include "main/utils.h"
using namespace std;

const int max_value = 6;

void occurTimesCore(vector<double> &vec, int n, int &cur_sum) {
  if (n == 0) {
    ++vec[cur_sum];
    return;
  }

  for (int i = 1; i <= max_value; ++i) {
    cur_sum += i;
    occurTimesCore(vec, n - 1, cur_sum);
    cur_sum -= i;
  }
}

vector<double> probilities_recursive(int n) {
  if (n < 1)
    return {};
  vector<double> ret(max_value * n + 1, 0);
  int cur_sum = 0;
  occurTimesCore(ret, n, cur_sum);
  double max_times = pow(max_value, n);
  for (size_t i = 0; i < ret.size(); ++i) {
    ret[i] /= max_times;
  }
  return ret;
}

vector<double> probilities_iter(int n) {
  if (n < 1)
    return {};
  vector<vector<double>> ret;
  ret.resize(2);
  for (int i = 0; i < ret.size(); ++i) {
    ret[i].resize(max_value * n + 1, 0);
  }
  int flag = 0;
  for (int i = 1; i <= max_value; ++i) {
    ret[flag][i] = 1;
  }

  for (int i = 2; i <= n; ++i) {
    ret[1 - flag].assign(max_value * n + 1, 0);
    for (int j = i; j < max_value * n + 1; ++j) {
      for (int k = 1; k < j && k <= max_value; ++k) {
        ret[1 - flag][j] += ret[flag][j - k];
      }
    }
    flag = 1 - flag;
  }

  double max_times = pow(max_value, n);
  for (size_t i = 0; i < ret[flag].size(); ++i) {
    ret[flag][i] = ret[flag][i] / max_times;
  }
  return ret[flag];
}

int main() {
  int n = 6;
  vector<double> ret_recursive = probilities_recursive(n);
  printVec("probilities recu", ret_recursive);

  vector<double> ret_iter = probilities_iter(n);
  printVec("probilities iter", ret_iter);

  return 0;
}
